<template>
  <div :class="$style.menu">
    <div
      v-if="treeStore.menuData.length < 6"
      :class="$style['menu-swiper']"
      style="height: auto;"
    >
      <div
        v-for="x, i in treeStore.menuData"
        :key="x.content_id"
        :class="slideClass(x, i)"
        :style="{ marginBottom: i === treeStore.menuData.length - 1 ? '' : `${slideSpace}px` }"
        @click="onSlideClick({ clickedIndex: i })"
      >
        <child-text :name="x.content_name" />
        <div
          v-if="treeStore.content_id === x.content_id"
          :class="$style['explaining']"
        >
          <explaining class="w-[50%] h-[40%]" />
        </div>
      </div>
    </div>
    <Swiper
      v-else
      :class="[$style['menu-swiper'], swiperClass, beforeClass]"
      direction="vertical"
      :slides-per-view="5"
      grab-cursor
      watch-overflow
      :space-between="slideSpace"
      centered-slides
      centered-slides-bounds
      @init="onSwiperInit"
      @from-edge="onFromEdge"
      @to-edge="onToEdge"
      @tap="onSlideClick"
      @transition-end="onTransitionEnd"
    >
      <swiper-slide
        v-for="x, i in treeStore.menuData"
        :key="x.content_id"
        :class="slideClass(x, i)"
      >
        <child-text :name="x.content_name" />
        <div
          v-if="treeStore.content_id === x.content_id"
          :class="$style['explaining']"
        >
          <explaining class="w-[50%] h-[40%]" />
        </div>
      </swiper-slide>
    </Swiper>
    <button
      :class="$style['btn-all']"
      @click="onSlideClick()"
    >
      <span class="relative z-1 flc">
        <span
          :class="$style['all-menu']"
          class="all-menu w-10px h-8px mr-1px inline-block"
        ></span>

        全部
      </span>
    </button>
  </div>
</template>

<script
  lang="ts"
  setup
  name="MenuList"
>
import { useTreeStore } from '@/store/tree'
import { useMenuTree } from '@/utils/comps'
import { childText } from './child'
import { isIos, iosVersion } from '@/utils/client'

const treeStore = useTreeStore()
const style = useCssModule()

const slideSpace = computed(() => Number(window.innerWidth * 0.025))
const menuSwiper = ref()
const swiperClass = ref('')
const beforeClass = ref('menu-show')
const activeIndex = computed(() => {
  const menuData = treeStore.menuData
  return menuData.findIndex(item => item.content_id === treeStore.content_id)
})
let catchLength = treeStore.menuData.length

const slideClass = (item, index) => {
  return {
    [style['menu-swiper-item']]: true,
    [style['slide-active']]: treeStore.content_id === item.content_id,
    [style['old']]: index < activeIndex.value,
    [style.last]: index === treeStore.menuData.length - 1
  }
}

watch(() => treeStore.content_id, (v) => {
  if (v && treeStore.menuData.length > 5) swiperTo(v)
})

const onSwiperInit = (swiper) => {
  menuSwiper.value = swiper
  if (swiper.isBeginning && swiper.isEnd) swiperClass.value = ''
  else if (swiper.isBeginning) swiperClass.value = style['show-top']
  swiperTo(treeStore.content_id)
}

const swiperTo = (content_id?) => {
  const menuData = treeStore.menuData
  let index = menuData.findIndex(item => item.content_id === (content_id || treeStore.content_id))
  if (index < 3) index = 2
  else if (index > menuData.length - 4) index = menuData.length - 3
  menuSwiper.value.slideTo(index)
}

const onSlideClick = async (swiper?) => {
  let id
  if (swiper) {
    const menuData = treeStore.menuData
    id = menuData[swiper.clickedIndex].content_id
  }
  setTimeout(() => {
    useMenuTree({ id })
  }, 60)
}

const onFromEdge = (swiper) => {
  if (swiper.slides.length <= 5) return
  if (swiper.slides.length === catchLength) swiperClass.value = style['no-top-bottom']
}

const onToEdge = (swiper) => {
  if (swiper.slides.length <= 5) return
  if (swiper.isBeginning && swiper.isEnd) swiperClass.value = ''
  else if (swiper.isBeginning) swiperClass.value = style['show-top']
  else if (swiper.isEnd) swiperClass.value = style['show-bottom']
}

let timer = null
const onTransitionEnd = () => {
  if (timer) {
    clearTimeout(timer)
    timer = null
  }
  timer = setTimeout(() => {
    swiperTo()
  }, 1000 * 5)
}

onBeforeUnmount(() => {
  if (timer) {
    clearTimeout(timer)
    timer = null
  }
})

onMounted(() => {
  if (isIos() && iosVersion()) {
    beforeClass.value = ''
  } else {
    beforeClass.value = style['menu-show']
  }
})

</script>

<style
  module
  lang="scss"
>
.menu {
  @apply flex flex-col w-full;
  color: rgba(59, 83, 121, 1);

  .menu-swiper {
    position: relative;
    width: 100%;
    height: 240px;
    padding: 0 10px;
    margin: 0 -10px;
    box-sizing: content-box;
    /* $mask: linear-gradient(to top, transparent 0, black 5%, black 95%, transparent 100%);
    mask: $mask;
    -webkit-mask: $mask; */

    &.show-bottom {
      &::before {
        display: block;
      }
    }

    &.show-top {
      &::after {
        display: block;
      }
    }

    &.no-top-bottom {

      &::after,
      &::before {
        display: block;
      }
    }

    .menu-swiper-item {
      @apply flc w-full relative flex-col;
      height: 40px;
      font-weight: 700;
      font-size: 10px;
      line-height: 12.5px;
      letter-spacing: 1px;
      padding: 0 6px;
      text-align: center;
      user-select: none;
      text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1), -1px -1px 1px rgba(255, 255, 255, 0.3);

      &::before {
        content: '';
        @apply absolute top-0 left-0 bottom-0 right-0 z-0 backdrop-filter backdrop-blur-10;
        background: linear-gradient(135deg, rgba(215, 228, 255, 0.39) 0%, rgba(215, 228, 255, 0.09) 100%);
        border-radius: 10px;
        border: 1px solid rgba(255, 255, 255, 0.3);
        box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.10);
      }

      &:not(.last)::after {
        content: '';
        @apply absolute z-0;
        left: 50%;
        bottom: -10px;
        width: 0;
        height: 10px;
        border-left: 1px dashed white;
      }

      &.old {
        &::after {
          border-color: rgba(70, 115, 238, 1);
        }
      }

      &:active,
      &.slide-active {
        color: rgba(70, 115, 238, 1);
      }

      &:active {
        &::before {
          border-color: rgba(70, 115, 238, 1);
        }
      }

      .explaining {
        @apply flc;
        position: absolute;
        top: calc(50% - 6px);
        z-index: 1;
        left: -6px;
        width: 13px;
        height: 13px;

        &::before {
          content: '';
          @apply absolute top-0 left-0 bottom-0 right-0 z-0 backdrop-filter backdrop-blur-20;
          border-radius: 50%;
          border: 1px solid rgba(255, 255, 255, 0.3);
          background: rgba(255, 255, 255, 0.3);
          box-shadow: 0px 1px 2px rgba(2, 29, 88, 0.1);
        }
      }
    }
  }

  .menu-show {

    &::before,
    &::after {
      content: '';
      @apply absolute;
      left: 10px;
      width: calc(100% - 20px);
      height: 10%;
      z-index: 2;
      display: none;
    }

    &::before {
      border-radius: 10px 10px 0 0;
      top: -1px;
      background: linear-gradient(to bottom, rgba(186, 204, 224, 1) 10%, transparent 100%);
    }

    &::after {
      border-radius: 0 0 10px 10px;
      bottom: -1px;
      background: linear-gradient(to top, rgba(186, 204, 224, 1) 10%, transparent 100%);
    }
  }

  .btn-all {
    @apply relative;
    height: 24.5px;
    margin-top: 10px;
    font-size: 10px;
    font-weight: 600;

    &::before {
      content: '';
      @apply absolute top-0 left-0 bottom-0 right-0 z-0 backdrop-filter backdrop-blur-10;
      border-radius: 4px 4px 10px 10px;
      border: 1px solid rgba(255, 255, 255, 0.3);
      background: linear-gradient(135deg, rgba(215, 228, 255, 0.39) 0%, rgba(215, 228, 255, 0.09) 100%);
    }

    .all-menu {
      background: url('@/assets/white-theme/icons/h5/nav-or-menu/all-menu.png') no-repeat;
      background-size: contain;
    }


    &:active {
      color: rgba(70, 115, 238, 1);

      .all-menu {
        background: url('@/assets/white-theme/icons/h5/nav-or-menu/all-menu-active.png') no-repeat;
        background-size: contain;
      }


      &::before {
        border-color: rgba(70, 115, 238, 1);
      }
    }
  }
}
</style>
